//
//  User.swift
//  CMB250716
//
//  Created by Andy Lau on 16/7/25.
//

import Foundation

// 会员等级
enum MembershipLevel: String, Codable, CaseIterable {
    case lv1 = "蓝调萌牛"
    case lv2 = "橙燃玩家"
    case lv3 = "紫域主理人"
    case lv4 = "金耀传说"
    
    var englishName: String {
        switch self {
        case .lv1: return "Neon Rookie"
        case .lv2: return "Hype Blaze"
        case .lv3: return "Vibe Regent"
        case .lv4: return "Aureus Legend"
        }
    }
    
    var displayName: String {
        return self.rawValue
    }
    
    var englishDisplayName: String {
        return self.englishName
    }
    
    var pointsRequired: Int {
        switch self {
        case .lv1: return 0
        case .lv2: return 201
        case .lv3: return 801
        case .lv4: return 1601
        }
    }
    
    // 积分抵扣规则：每多少积分减5元
    var pointsPerDiscount: Int {
        switch self {
        case .lv1: return 100  // 每100分减5元
        case .lv2: return 80    // 每80分减5元
        case .lv3: return 50      // 每50分减5元
        case .lv4: return 30  // 每30分减5元
        }
    }
    
    // 最低抵扣积分要求
    var minimumPointsForDiscount: Int {
        return pointsPerDiscount
    }
}

// 用户模型
struct User: Identifiable, Codable {
    var id: UUID
    var phoneNumber: String
    var memberID: String // 会员ID，格式：CMB-年份月份+递增编号
    var name: String?
    var email: String?
    var address: String?
    var birthYear: String?
    var birthMonth: String?
    var gender: String?
    var points: Int // 当前可用积分余额
    var totalPointsEarned: Int // 历史累计积分（用于会员升级）
    var membershipLevel: MembershipLevel
    
    // 新增属性
    var couponUsageHistory: [CouponUsageRecord] = []
    var ownedCoupons: [UserCoupon] = [] // 用户拥有的礼券
    let registrationDate: Date
    let joinDate: Date
    var monthlyPointsEarned: Int
    var totalSpent: Double
    var socialMediaAccounts: SocialMediaAccounts
    var avatarInitials: String?
    
    // 验证状态
    var isPhoneVerified: Bool = false
    var isEmailVerified: Bool = false
    
    // 换绑相关
    var lastPhoneChangeDate: Date?
    var lastEmailChangeDate: Date?
    var phoneChangeHistory: [ContactChangeRecord] = []
    var emailChangeHistory: [ContactChangeRecord] = []
    
    // 生物识别登录
    var biometricLoginEnabled: Bool = false
    var lastLoginDate: Date?
    var loginDeviceId: String?
    
    // JWT Token for persistent login
    var authToken: String?
    var tokenExpiryDate: Date?
    
    // 邀请系统相关字段
    var referrerID: String? // 推荐人ID（邀请者的memberID）
    var inviteHistory: [InviteRecord] = [] // 邀请历史记录
    var isInviteRewardClaimed: Bool = false // 是否已领取邀请奖励
    
    // 会员信息完善状态
    var isMemberInfoComplete: Bool {
        return name != nil && !name!.isEmpty &&
               email != nil && !email!.isEmpty &&
               birthYear != nil && !birthYear!.isEmpty &&
               birthMonth != nil && !birthMonth!.isEmpty
    }
    
    init(phoneNumber: String, name: String? = nil, email: String? = nil, referrerID: String? = nil) {
        self.id = UUID()
        self.phoneNumber = phoneNumber
        self.memberID = User.generateMemberID() // 自动生成会员ID
        User.saveMemberID(self.memberID) // 保存会员编码以防重复
        self.name = name
        self.email = email
        self.address = nil
        self.birthYear = nil
        self.birthMonth = nil
        self.gender = nil
        self.points = 0
        self.totalPointsEarned = 0
        self.membershipLevel = .lv1
        self.registrationDate = Date()
        self.joinDate = Date()
        self.monthlyPointsEarned = 0
        self.totalSpent = 0.0
        self.socialMediaAccounts = SocialMediaAccounts()
        self.isPhoneVerified = true // 默认电话已验证（因为是通过电话注册的）
        self.isEmailVerified = false
        
        // 邀请系统初始化
        self.referrerID = referrerID
    }
    
    // 生成会员ID的静态方法
    static func generateMemberID() -> String {
        var memberID: String
        var attempts = 0
        let maxAttempts = 100
        
        repeat {
            // 随机选择前缀：C、M或B
            let prefixes = ["C", "M", "B"]
            let randomPrefix = prefixes.randomElement()!
            
            // 生成4位随机数字
            let randomNumbers = String(format: "%04d", Int.random(in: 0...9999))
            
            // 生成1位随机字母（大写）
            let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            let randomLetter = String(letters.randomElement()!)
            
            memberID = "\(randomPrefix)\(randomNumbers)\(randomLetter)"
            attempts += 1
            
            // 检查是否已存在此会员编码
            if !isMemberIDExists(memberID) {
                break
            }
        } while attempts < maxAttempts
        
        return memberID
    }
    
    // 检查会员编码是否已存在
    private static func isMemberIDExists(_ memberID: String) -> Bool {
        let existingMemberIDs = UserDefaults.standard.stringArray(forKey: "existingMemberIDs") ?? []
        return existingMemberIDs.contains(memberID)
    }
    
    // 保存新的会员编码
    private static func saveMemberID(_ memberID: String) {
        var existingMemberIDs = UserDefaults.standard.stringArray(forKey: "existingMemberIDs") ?? []
        existingMemberIDs.append(memberID)
        UserDefaults.standard.set(existingMemberIDs, forKey: "existingMemberIDs")
    }
    
    // 获取当前最大的会员编号
    private static func getCurrentMaxMemberNumber() -> Int {
        let savedNumber = UserDefaults.standard.integer(forKey: "maxMemberNumber")
        return savedNumber == 0 ? 1687 : savedNumber // 如果没有保存过，从1687开始，下一个就是1688
    }
    
    mutating func addPoints(_ points: Int) {
        self.points += points
        self.totalPointsEarned += points
        updateMembershipLevel()
    }
    
    mutating func deductPoints(_ points: Int) -> Bool {
        if self.points >= points {
            self.points -= points
            return true
        }
        return false
    }
    
    private mutating func updateMembershipLevel() {
        // 基于历史累计积分进行会员升级，而不是当前积分余额
        if totalPointsEarned >= MembershipLevel.lv4.pointsRequired {
            membershipLevel = .lv4
        } else if totalPointsEarned >= MembershipLevel.lv3.pointsRequired {
            membershipLevel = .lv3
        } else if totalPointsEarned >= MembershipLevel.lv2.pointsRequired {
            membershipLevel = .lv2
        } else {
            membershipLevel = .lv1
        }
    }
    
    // 新增方法
    func canUseCoupon(_ coupon: Coupon) -> Bool {
        // 检查时间适用性
        if !coupon.isApplicableAtCurrentTime() {
            return false
        }
        
        // 检查使用频率
        if coupon.usageFrequency != nil {
            let lastUsedDate = couponUsageHistory
                .filter { $0.couponCode == coupon.code }
                .max(by: { $0.usedDate < $1.usedDate })?.usedDate
            
            if !coupon.canUseBasedOnFrequency(lastUsedDate: lastUsedDate) {
                return false
            }
        }
        
        return true
    }
    
    mutating func recordCouponUsage(_ coupon: Coupon) {
        let record = CouponUsageRecord(
            couponCode: coupon.code,
            usedDate: Date()
        )
        couponUsageHistory.append(record)
    }
    
    func getExpiringCoupons(within days: Int = 3) -> [UserCoupon] {
        let targetDate = Calendar.current.date(byAdding: .day, value: days, to: Date()) ?? Date()
        return ownedCoupons.filter { userCoupon in
            userCoupon.expiryDate <= targetDate && userCoupon.expiryDate >= Date()
        }
    }
}

// 社交媒体账号
struct SocialMediaAccounts: Codable {
    var instagram: String?
    var facebook: String?
    var tiktok: String?
    var whatsapp: String?
    var telegram: String?
    var wechat: String?
    
    init(instagram: String? = nil, facebook: String? = nil, tiktok: String? = nil, whatsapp: String? = nil, telegram: String? = nil, wechat: String? = nil) {
        self.instagram = instagram
        self.facebook = facebook
        self.tiktok = tiktok
        self.whatsapp = whatsapp
        self.telegram = telegram
        self.wechat = wechat
    }
}



// 新增结构体
struct CouponUsageRecord: Codable {
    let couponCode: String
    let usedDate: Date
}

struct UserCoupon: Codable {
    let couponCode: String
    let grantedDate: Date
    let expiryDate: Date
    var isUsed: Bool
    
    init(couponCode: String, grantedDate: Date, relativeDuration: RelativeDuration) {
        self.couponCode = couponCode
        self.grantedDate = grantedDate
        self.expiryDate = UserCoupon.calculateExpiryDate(from: grantedDate, duration: relativeDuration)
        self.isUsed = false
    }
    
    private static func calculateExpiryDate(from startDate: Date, duration: RelativeDuration) -> Date {
        let calendar = Calendar.current
        switch duration {
        case .days(let days):
            return calendar.date(byAdding: .day, value: days, to: startDate) ?? startDate
        case .weeks(let weeks):
            return calendar.date(byAdding: .weekOfYear, value: weeks, to: startDate) ?? startDate
        case .months(let months):
            return calendar.date(byAdding: .month, value: months, to: startDate) ?? startDate
        case .years(let years):
            return calendar.date(byAdding: .year, value: years, to: startDate) ?? startDate
        }
    }
}

// 联系方式变更记录
struct ContactChangeRecord: Codable {
    let id: UUID
    let oldValue: String
    let newValue: String
    let changeDate: Date
    let verificationMethod: String // "SMS", "Email", "Manual"
    let isSuccessful: Bool
    
    init(oldValue: String, newValue: String, verificationMethod: String, isSuccessful: Bool = true) {
        self.id = UUID()
        self.oldValue = oldValue
        self.newValue = newValue
        self.changeDate = Date()
        self.verificationMethod = verificationMethod
        self.isSuccessful = isSuccessful
    }
}

// 验证码类型
enum VerificationType {
    case phoneChange(oldPhone: String, newPhone: String)
    case emailChange(oldEmail: String, newEmail: String)
    case login(phone: String)
    case biometricSetup
}

// 验证码记录
struct VerificationRecord {
    let id: UUID
    let type: VerificationType
    let code: String
    let sentDate: Date
    let expiryDate: Date
    var isUsed: Bool
    
    init(type: VerificationType, code: String) {
        self.id = UUID()
        self.type = type
        self.code = code
        self.sentDate = Date()
        self.expiryDate = Calendar.current.date(byAdding: .minute, value: 5, to: Date()) ?? Date()
        self.isUsed = false
    }
    
    var isValid: Bool {
        return !isUsed && Date() < expiryDate
    }
}

// 邀请记录
struct InviteRecord: Codable, Hashable {
    let id: UUID
    let invitedMemberID: String // 被邀请人的会员ID
    let invitedPhone: String // 被邀请人的手机号
    let inviteDate: Date // 邀请日期
    let registrationDate: Date? // 被邀请人注册日期
    let isSuccessful: Bool // 是否成功注册
    let rewardClaimed: Bool // 是否已领取奖励
    
    init(invitedMemberID: String, invitedPhone: String, isSuccessful: Bool = false) {
        self.id = UUID()
        self.invitedMemberID = invitedMemberID
        self.invitedPhone = invitedPhone
        self.inviteDate = Date()
        self.registrationDate = isSuccessful ? Date() : nil
        self.isSuccessful = isSuccessful
        self.rewardClaimed = false
    }
}